using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

namespace Odb_base.Interop.Interfaces
{
  [TypeLibType(TypeLibTypeFlags.FDual |
               TypeLibTypeFlags.FDispatchable |
               TypeLibTypeFlags.FNonExtensible)]
  [Guid("27354130-7F64-5B0F-8F00-5D77AFBE261E"), ComImport]
  public interface IDiscMaster2
  {
    /// <summary>
    /// Enumerates the list of CD/DVD devices on the system
    /// </summary>
    /// <returns></returns>
    [TypeLibFunc(65)]
    [DispId(-4)]
    IEnumerator GetEnumerator();

    /// <summary>
    /// Gets a single recorder's ID
    /// </summary>
    /// <param name="index">Zero based index</param>
    /// <returns>Recorder's unique id</returns>
    [DispId(0)]
    string this[int index] { get; }

    /// <summary>
    /// The current number of recorders in the system.
    /// </summary>
    [DispId(1)]
    int Count { get; }

    /// <summary>
    /// Whether IMAPI is running in an environment with optical 
    /// devices and permission to access them.
    /// </summary>
    [DispId(2)]
    bool IsSupportedEnvironment { get; }
  }

  [TypeLibType(TypeLibTypeFlags.FDual |
               TypeLibTypeFlags.FDispatchable |
               TypeLibTypeFlags.FNonExtensible)]
  [Guid("27354133-7F64-5B0F-8F00-5D77AFBE261E"), ComImport]
  public interface IDiscRecorder2
  {
    /// <summary>
    /// Ejects the media (if any) and opens the tray
    /// </summary>
    [DispId(256)]
    void EjectMedia();

    /// <summary>
    /// Close the media tray and load any media in the tray.
    /// </summary>
    [DispId(257)]
    void CloseTray();

    /// <summary>
    /// Acquires exclusive access to device. 
    /// May be called multiple times.
    /// </summary>
    /// <param name="force"></param>
    /// <param name="clientName">App Id</param>
    [DispId(258)]
    void AcquireExclusiveAccess(bool force, string clientName);

    /// <summary>
    /// Releases exclusive access to device. 
    /// Call once per AcquireExclusiveAccess().
    /// </summary>
    [DispId(259)]
    void ReleaseExclusiveAccess();

    /// <summary>
    /// Disables Media Change Notification (MCN).
    /// </summary>
    [DispId(260)]
    void DisableMcn();

    /// <summary>
    /// Re-enables Media Change Notification after a call to DisableMcn()
    /// </summary>
    [DispId(261)]
    void EnableMcn();

    /// <summary>
    /// Initialize the recorder, opening a handle to the specified recorder.
    /// </summary>
    /// <param name="recorderUniqueId"></param>
    [DispId(262)]
    void InitializeDiscRecorder(string recorderUniqueId);

    /// <summary>
    /// The unique ID used to initialize the recorder.
    /// </summary>
    [DispId(0)]
    string ActiveDiscRecorder { get; }

    /// <summary>
    /// The vendor ID in the device's INQUIRY data.
    /// </summary>
    [DispId(513)]
    string VendorId { get; }

    /// <summary>
    /// The Product ID in the device's INQUIRY data.
    /// </summary>
    [DispId(514)]
    string ProductId { get; }

    /// <summary>
    /// The Product Revision in the device's INQUIRY data.
    /// </summary>
    [DispId(515)]
    string ProductRevision { get; }

    /// <summary>
    /// Get the unique volume name (this is not a drive letter).
    /// </summary>
    [DispId(516)]
    string VolumeName { get; }

    /// <summary>
    /// Drive letters and NTFS mount points to access the recorder.
    /// </summary>
    [DispId(517)]
    object[] VolumePathNames { get; }

    /// <summary>
    /// One of the volume names associated with the recorder.
    /// </summary>
    [DispId(518)]
    bool DeviceCanLoadMedia { get; }

    /// <summary>
    /// Gets the legacy 'device number' associated with the recorder. 
    /// This number is not guaranteed to be static.
    /// </summary>
    [DispId(519)]
    int LegacyDeviceNumber { get; }

    /// <summary>
    /// Gets a list of all feature pages supported by the device
    /// </summary>
    [DispId(520)]
    Array SupportedFeaturePages { get; }

    /// <summary>
    /// Gets a list of all feature pages with 'current' bit set to true
    /// </summary>
    [DispId(521)]
    Array CurrentFeaturePages { get; }

    /// <summary>
    /// Gets a list of all profiles supported by the device
    /// </summary>
    [DispId(522)]
    Array SupportedProfiles { get; }

    /// <summary>
    /// Gets a list of all profiles with 'currentP' bit set to true
    /// </summary>
    [DispId(523)]
    Array CurrentProfiles { get; }

    /// <summary>
    /// Gets a list of all MODE PAGES supported by the device
    /// </summary>
    [DispId(524)]
    Array SupportedModePages { get; }

    /// <summary>
    /// Queries the device to determine who, if anyone, has acquired exclusive access
    /// </summary>
    [DispId(525)]
    string ExclusiveAccessOwner { get; }
  }

  [
    ComImport,
    Guid("27354152-8F64-5B0F-8F00-5D77AFBE261E"),
    InterfaceType(ComInterfaceType.InterfaceIsDual)
  ]
  public interface IDiscFormat2
  {
    /// <summary>
    /// Determines if the recorder object supports the given format
    /// </summary>
    /// <param name="Recorder"></param>
    /// <returns></returns>
    [DispId(2048)]
    [return : MarshalAs(UnmanagedType.VariantBool)]
    bool IsRecorderSupported(IDiscRecorder2 Recorder);

    /// <summary>
    /// Determines if the current media in a supported recorder object
    /// supports the given format
    /// </summary>
    /// <param name="Recorder"></param>
    /// <returns></returns>
    [DispId(2049)]
    [return : MarshalAs(UnmanagedType.VariantBool)]
    bool IsCurrentMediaSupported(IDiscRecorder2 Recorder);

    /// <summary>
    /// Determines if the current media is reported as physically blank
    /// by the drive
    /// </summary>
    [DispId(1792)]
    bool MediaPhysicallyBlank { [return : MarshalAs(UnmanagedType.VariantBool)]
    get; }

    /// <summary>
    /// Attempts to determine if the media is blank using heuristics
    /// (mainly for DVD+RW and DVD-RAM media)
    /// </summary>
    [DispId(1793)]
    bool MediaHeuristicallyBlank { [return : MarshalAs(UnmanagedType.VariantBool)]
    get; }

    /// <summary>
    /// Supported media types
    /// </summary>
    [DispId(1794)]
    object[] SupportedMediaTypes { [return : MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)]
    get; }
  }

  [
    ComImport,
    Guid("27354156-8F64-5B0F-8F00-5D77AFBE261E"),
    InterfaceType(ComInterfaceType.InterfaceIsDual)
  ]
  public interface IDiscFormat2Erase : IDiscFormat2
  {
    

    /// <summary>
    /// Determines if the recorder object supports the given format
    /// </summary>
    /// <param name="Recorder"></param>
    /// <returns></returns>
    [DispId(2048)]
    [return : MarshalAs(UnmanagedType.VariantBool)]
    new bool IsRecorderSupported(IDiscRecorder2 Recorder);

    /// <summary>
    /// Determines if the current media in a supported recorder object
    /// supports the given format
    /// </summary>
    /// <param name="Recorder"></param>
    /// <returns></returns>
    [DispId(2049)]
    [return : MarshalAs(UnmanagedType.VariantBool)]
    new bool IsCurrentMediaSupported(IDiscRecorder2 Recorder);

    /// <summary>
    /// Determines if the current media is reported as physically blank
    /// by the drive
    /// </summary>
    [DispId(1792)]
    new bool MediaPhysicallyBlank { [return : MarshalAs(UnmanagedType.VariantBool)]
    get; }

    /// <summary>
    /// Attempts to determine if the media is blank using heuristics
    /// (mainly for DVD+RW and DVD-RAM media)
    /// </summary>
    [DispId(1793)]
    new bool MediaHeuristicallyBlank { [return : MarshalAs(UnmanagedType.VariantBool)]
    get; }

    /// <summary>
    /// Supported media types
    /// </summary>
    [DispId(1794)]
    new Object[] SupportedMediaTypes { [return : MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)]
    get; }

    // IDiscFormat2Erase

    [DispId(0x100)]
    IDiscRecorder2 Recorder { set; [return : MarshalAs(UnmanagedType.Interface)]
    get; }

    [DispId(0x101)]
    bool FullErase { set; [return : MarshalAs(UnmanagedType.VariantBool)]
    get; }

    [DispId(0x102)]
    IMAPI_MEDIA_PHYSICAL_TYPE CurrentPhysicalMediaType { get; }

    [DispId(0x103)]
    String ClientName { set; [return : MarshalAs(UnmanagedType.BStr)]
    get; }

    [DispId(0x201)]
    void EraseMedia();
  }

 

  [TypeLibType(TypeLibTypeFlags.FCanCreate)]
  [ClassInterface(ClassInterfaceType.None)]
  [Guid("2735412B-7F64-5B0F-8F00-5D77AFBE261E"), ComImport]
  public class MsftDiscFormat2EraseClass
  {
  }

  [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  [Guid("27354132-7F64-5B0F-8F00-5D77AFBE261E")]
  public interface IDiscRecorder2Ex
  {
    /// <summary>
    /// Send a command to the device that does not transfer any data
    /// </summary>
    /// <param name="Cdb"></param>
    /// <param name="CdbSize"></param>
    /// <param name="SenseBuffer"></param>
    /// <param name="Timeout"></param>
    void SendCommandNoData(ref byte Cdb, uint CdbSize, byte[] SenseBuffer, uint Timeout);

    /// <summary>
    /// Send a command to the device that requires data sent to the device
    /// </summary>
    /// <param name="Cdb"></param>
    /// <param name="CdbSize"></param>
    /// <param name="SenseBuffer"></param>
    /// <param name="Timeout"></param>
    /// <param name="Buffer"></param>
    /// <param name="BufferSize"></param>
    void SendCommandSendDataToDevice(ref byte Cdb, uint CdbSize, byte[] SenseBuffer, uint Timeout, ref byte Buffer,
                                     uint BufferSize);

    /// <summary>
    /// Send a command to the device that requests data from the device
    /// </summary>
    /// <param name="Cdb"></param>
    /// <param name="CdbSize"></param>
    /// <param name="SenseBuffer"></param>
    /// <param name="Timeout"></param>
    /// <param name="Buffer"></param>
    /// <param name="BufferSize"></param>
    /// <param name="BufferFetched"></param>
    void SendCommandGetDataFromDevice(ref byte Cdb, uint CdbSize, byte[] SenseBuffer, uint Timeout, out byte Buffer,
                                      uint BufferSize, out uint BufferFetched);

    /// <summary>
    /// Read a DVD Structure from the media
    /// </summary>
    /// <param name="format"></param>
    /// <param name="address"></param>
    /// <param name="layer"></param>
    /// <param name="agid"></param>
    /// <param name="data"></param>
    /// <param name="Count"></param>
    void ReadDvdStructure(uint format, uint address, uint layer, uint agid, IntPtr data, out uint Count);

    /// <summary>
    /// Read a DVD Structure from the media
    /// </summary>
    /// <param name="format"></param>
    /// <param name="data"></param>
    /// <param name="Count"></param>
    void SendDvdStructure(uint format, ref byte data, uint Count);

    /// <summary>
    /// Get the full adapter descriptor (via IOCTL_STORAGE_QUERY_PROPERTY).
    /// </summary>
    /// <param name="data"></param>
    /// <param name="byteSize"></param>
    void GetAdapterDescriptor(IntPtr data, out uint byteSize);

    /// <summary>
    /// Get the full device descriptor (via IOCTL_STORAGE_QUERY_PROPERTY).
    /// </summary>
    /// <param name="data"></param>
    /// <param name="byteSize"></param>
    void GetDeviceDescriptor(IntPtr data, out uint byteSize);

    /// <summary>
    /// Gets data from a READ_DISC_INFORMATION command
    /// </summary>
    /// <param name="discInformation"></param>
    /// <param name="byteSize"></param>
    void GetDiscInformation(IntPtr discInformation, out uint byteSize);

    /// <summary>
    /// Gets data from a READ_TRACK_INFORMATION command
    /// </summary>
    /// <param name="address"></param>
    /// <param name="addressType"></param>
    /// <param name="trackInformation"></param>
    /// <param name="byteSize"></param>
    void GetTrackInformation(uint address, IMAPI_READ_TRACK_ADDRESS_TYPE addressType, IntPtr trackInformation,
                             out uint byteSize);

    /// <summary>
    /// Gets a feature's data from a GET_CONFIGURATION command
    /// </summary>
    /// <param name="requestedFeature"></param>
    /// <param name="currentFeatureOnly"></param>
    /// <param name="featureData"></param>
    /// <param name="byteSize"></param>
    void GetFeaturePage(IMAPI_FEATURE_PAGE_TYPE requestedFeature, sbyte currentFeatureOnly, IntPtr featureData,
                        out uint byteSize);

    /// <summary>
    /// Gets data from a MODE_SENSE10 command
    /// </summary>
    /// <param name="requestedModePage"></param>
    /// <param name="requestType"></param>
    /// <param name="modePageData"></param>
    /// <param name="byteSize"></param>
    void GetModePage(IMAPI_MODE_PAGE_TYPE requestedModePage, IMAPI_MODE_PAGE_REQUEST_TYPE requestType,
                     IntPtr modePageData, out uint byteSize);

    /// <summary>
    /// Sets mode page data using MODE_SELECT10 command
    /// </summary>
    /// <param name="requestType"></param>
    /// <param name="data"></param>
    /// <param name="byteSize"></param>
    void SetModePage(IMAPI_MODE_PAGE_REQUEST_TYPE requestType, ref byte data, uint byteSize);

    /// <summary>
    /// Gets a list of all feature pages supported by the device
    /// </summary>
    /// <param name="currentFeatureOnly"></param>
    /// <param name="featureData"></param>
    /// <param name="byteSize"></param>
    void GetSupportedFeaturePages(sbyte currentFeatureOnly, IntPtr featureData, out uint byteSize);

    /// <summary>
    /// Gets a list of all PROFILES supported by the device
    /// </summary>
    /// <param name="currentOnly"></param>
    /// <param name="profileTypes"></param>
    /// <param name="validProfiles"></param>
    void GetSupportedProfiles(sbyte currentOnly, IntPtr profileTypes, out uint validProfiles);

    /// <summary>
    /// Gets a list of all MODE PAGES supported by the device
    /// </summary>
    /// <param name="requestType"></param>
    /// <param name="modePageTypes"></param>
    /// <param name="validPages"></param>
    void GetSupportedModePages(IMAPI_MODE_PAGE_REQUEST_TYPE requestType, IntPtr modePageTypes, out uint validPages);

    /// <summary>
    /// The byte alignment requirement mask for this device.
    /// </summary>
    /// <returns></returns>
    uint GetByteAlignmentMask();

    /// <summary>
    /// The maximum non-page-aligned transfer size for this device.
    /// </summary>
    /// <returns></returns>
    uint GetMaximumNonPageAlignedTransferSize();

    /// <summary>
    /// The maximum non-page-aligned transfer size for this device.
    /// </summary>
    /// <returns></returns>
    uint GetMaximumPageAlignedTransferSize();
  }

  [TypeLibType(TypeLibTypeFlags.FDual |
               TypeLibTypeFlags.FDispatchable |
               TypeLibTypeFlags.FNonExtensible)]
  [Guid("27354153-9F64-5B0F-8F00-5D77AFBE261E")]
  public interface IDiscFormat2Data
  {
    // IDiscFormat2
    /// <summary>
    /// Determines if the recorder object supports the given format
    /// </summary>
    /// <param name="Recorder"></param>
    /// <returns></returns>
    [DispId(2048)]
    bool IsRecorderSupported(IDiscRecorder2 Recorder);

    /// <summary>
    /// Determines if the current media in a supported recorder object 
    /// supports the given format
    /// </summary>
    /// <param name="Recorder"></param>
    /// <returns></returns>
    [DispId(2049)]
    bool IsCurrentMediaSupported(IDiscRecorder2 Recorder);

    /// <summary>
    /// Determines if the current media is reported as physically blank 
    /// by the drive
    /// </summary>
    [DispId(1792)]
    bool MediaPhysicallyBlank { get; }

    /// <summary>
    /// Attempts to determine if the media is blank using heuristics 
    /// (mainly for DVD+RW and DVD-RAM media)
    /// </summary>
    [DispId(1793)]
    bool MediaHeuristicallyBlank { get; }

    /// <summary>
    /// Supported media types
    /// </summary>
    [DispId(1794)]
    Array SupportedMediaTypes { get; }

    // IDiscFormat2Data
    /// <summary>
    /// The disc recorder to use
    /// </summary>
    [DispId(256)]
    IDiscRecorder2 Recorder { set; get; }

    /// <summary>
    /// Buffer Underrun Free recording should be disabled
    /// </summary>
    [DispId(257)]
    bool BufferUnderrunFreeDisabled { set; get; }

    /// <summary>
    /// Postgap is included in image
    /// </summary>
    [DispId(260)]
    bool PostgapAlreadyInImage { set; get; }

    /// <summary>
    /// The state (usability) of the current media
    /// </summary>
    [DispId(262)]
    IMAPI_FORMAT2_DATA_MEDIA_STATE CurrentMediaStatus { get; }

    /// <summary>
    /// The write protection state of the current media.
    /// </summary>
    [DispId(263)]
    IMAPI_MEDIA_WRITE_PROTECT_STATE WriteProtectStatus { get; }

    /// <summary>
    /// Total sectors available on the media (used + free).
    /// </summary>
    [DispId(264)]
    int TotalSectorsOnMedia { get; }

    /// <summary>
    /// Free sectors available on the media.
    /// </summary>
    [DispId(265)]
    int FreeSectorsOnMedia { get; }

    /// <summary>
    /// Next writable address on the media (also used sectors).
    /// </summary>
    [DispId(266)]
    int NextWritableAddress { get; }

    /// <summary>
    /// The first sector in the previous session on the media.
    /// </summary>
    [DispId(267)]
    int StartAddressOfPreviousSession { get; }

    /// <summary>
    /// The last sector in the previous session on the media.
    /// </summary>
    [DispId(268)]
    int LastWrittenAddressOfPreviousSession { get; }

    /// <summary>
    /// Prevent further additions to the file system
    /// </summary>
    [DispId(269)]
    bool ForceMediaToBeClosed { set; get; }

    /// <summary>
    /// Default is to maximize compatibility with DVD-ROM. 
    /// May be disabled to reduce time to finish writing the disc or 
    /// increase usable space on the media for later writing.
    /// </summary>
    [DispId(270)]
    bool DisableConsumerDvdCompatibilityMode { set; get; }

    /// <summary>
    /// Get the current physical media type.
    /// </summary>
    [DispId(271)]
    IMAPI_MEDIA_PHYSICAL_TYPE CurrentPhysicalMediaType { get; }

    /// <summary>
    /// The friendly name of the client 
    /// (used to determine recorder reservation conflicts).
    /// </summary>
    [DispId(272)]
    string ClientName { set; get; }

    /// <summary>
    /// The last requested write speed.
    /// </summary>
    [DispId(273)]
    int RequestedWriteSpeed { get; }

    /// <summary>
    /// The last requested rotation type.
    /// </summary>
    [DispId(274)]
    bool RequestedRotationTypeIsPureCAV { get; }

    /// <summary>
    /// The drive's current write speed.
    /// </summary>
    [DispId(275)]
    int CurrentWriteSpeed { get; }

    /// <summary>
    /// The drive's current rotation type.
    /// </summary>
    [DispId(276)]
    bool CurrentRotationTypeIsPureCAV { get; }

    /// <summary>
    /// Gets an array of the write speeds supported for the 
    /// attached disc recorder and current media
    /// </summary>
    [DispId(277)]
    object[] SupportedWriteSpeeds { get; }

    /// <summary>
    /// Gets an array of the detailed write configurations 
    /// supported for the attached disc recorder and current media
    /// </summary>
    [DispId(278)]
    object[] SupportedWriteSpeedDescriptors { get; }

    /// <summary>
    /// Forces the Datawriter to overwrite the disc on overwritable media types
    /// </summary>
    [DispId(279)]
    bool ForceOverwrite { set; get; }

    /// <summary>
    /// Returns the array of available multi-session interfaces. 
    /// The array shall not be empty
    /// </summary>
    [DispId(280)]
    Array MultisessionInterfaces { get; }

    /// <summary>
    /// Writes all the data provided in the IStream to the device
    /// </summary>
    /// <param name="data"></param>
    [DispId(512)]
    void Write(IStream data);

    /// <summary>
    /// Cancels the current write operation
    /// </summary>
    [DispId(513)]
    void CancelWrite();

    /// <summary>
    /// Sets the write speed (in sectors per second) of the attached disc recorder
    /// </summary>
    /// <param name="RequestedSectorsPerSecond"></param>
    /// <param name="RotationTypeIsPureCAV"></param>
    [DispId(514)]
    void SetWriteSpeed(int RequestedSectorsPerSecond, bool RotationTypeIsPureCAV);
  }

  [TypeLibType(TypeLibTypeFlags.FDual |
               TypeLibTypeFlags.FDispatchable |
               TypeLibTypeFlags.FNonExtensible)]
  [Guid("2C941FE1-975B-59BE-A960-9A2A262853A5")]
  public interface IFileSystemImage
  {
    /// <summary>
    /// Root directory item
    /// </summary>
    [DispId(0)]
    IFsiDirectoryItem Root { get; }

    /// <summary>
    /// Disc start block for the image
    /// </summary>
    [DispId(1)]
    int SessionStartBlock { get; set; }

    /// <summary>
    /// Maximum number of blocks available for the image
    /// </summary>
    [DispId(2)]
    int FreeMediaBlocks { get; set; }

    /// <summary>
    /// Set maximum number of blocks available based on the recorder supported discs. 
    /// 0 for unknown maximum may be set.
    /// </summary>
    /// <param name="discRecorder"></param>
    [DispId(36)]
    void SetMaxMediaBlocksFromDevice(IDiscRecorder2 discRecorder);

    /// <summary>
    /// Number of blocks in use
    /// </summary>
    [DispId(3)]
    int UsedBlocks { get; }

    /// <summary>
    /// Volume name
    /// </summary>
    [DispId(4)]
    string VolumeName { get; set; }

    /// <summary>
    /// Imported Volume name
    /// </summary>
    [DispId(5)]
    string ImportedVolumeName { get; }

    /// <summary>
    /// Boot image and boot options
    /// </summary>
    [DispId(6)]
    IBootOptions BootImageOptions { get; set; }

    /// <summary>
    /// Number of files in the image
    /// </summary>
    [DispId(7)]
    int FileCount { get; }

    /// <summary>
    /// Number of directories in the image
    /// </summary>
    [DispId(8)]
    int DirectoryCount { get; }

    /// <summary>
    /// Temp directory for stash files
    /// </summary>
    [DispId(9)]
    string WorkingDirectory { get; set; }

    /// <summary>
    /// Change point identifier
    /// </summary>
    [DispId(10)]
    int ChangePoint { get; }

    /// <summary>
    /// Strict file system compliance option
    /// </summary>
    [DispId(11)]
    bool StrictFileSystemCompliance { get; set; }

    /// <summary>
    /// If true, indicates restricted character set is being used for file and directory names
    /// </summary>
    [DispId(12)]
    bool UseRestrictedCharacterSet { get; set; }

    /// <summary>
    /// File systems to create
    /// </summary>
    [DispId(13)]
    FsiFileSystems FileSystemsToCreate { get; set; }

    /// <summary>
    /// File systems supported
    /// </summary>
    [DispId(14)]
    FsiFileSystems FileSystemsSupported { get; }

    /// <summary>
    /// UDF revision
    /// </summary>
    [DispId(37)]
    int UDFRevision { set; get; }

    /// <summary>
    /// UDF revision(s) supported
    /// </summary>
    [DispId(31)]
    object[] UDFRevisionsSupported { get; }

    /// <summary>
    /// Select filesystem types and image size based on the current media
    /// </summary>
    /// <param name="discRecorder"></param>
    [DispId(32)]
    void ChooseImageDefaults(IDiscRecorder2 discRecorder);

    /// <summary>
    /// Select filesystem types and image size based on the media type
    /// </summary>
    /// <param name="value"></param>
    [DispId(33)]
    void ChooseImageDefaultsForMediaType(IMAPI_MEDIA_PHYSICAL_TYPE value);

    /// <summary>
    /// ISO compatibility level to create
    /// </summary>
    [DispId(34)]
    int ISO9660InterchangeLevel { set; get; }

    /// <summary>
    /// ISO compatibility level(s) supported
    /// </summary>
    [DispId(38)]
    object[] ISO9660InterchangeLevelsSupported { get; }

    /// <summary>
    /// Create result image stream
    /// </summary>
    /// <returns></returns>
    [DispId(15)]
    IFileSystemImageResult CreateResultImage();

    /// <summary>
    /// Check for existance an item in the file system
    /// </summary>
    /// <param name="FullPath"></param>
    /// <returns></returns>
    [DispId(16)]
    FsiItemType Exists(string FullPath);

    /// <summary>
    /// Return a string useful for identifying the current disc
    /// </summary>
    /// <returns></returns>
    [DispId(18)]
    string CalculateDiscIdentifier();

    /// <summary>
    /// Identify file systems on a given disc
    /// </summary>
    /// <param name="discRecorder"></param>
    /// <returns></returns>
    [DispId(19)]
    FsiFileSystems IdentifyFileSystemsOnDisc(IDiscRecorder2 discRecorder);

    /// <summary>
    /// Identify which of the specified file systems would be imported by default
    /// </summary>
    /// <param name="fileSystems"></param>
    /// <returns></returns>
    [DispId(20)]
    FsiFileSystems GetDefaultFileSystemForImport(FsiFileSystems fileSystems);

    /// <summary>
    /// Import the default file system on the current disc
    /// </summary>
    /// <returns></returns>
    [DispId(21)]
    FsiFileSystems ImportFileSystem();

    /// <summary>
    /// Import a specific file system on the current disc
    /// </summary>
    /// <param name="fileSystemToUse"></param>
    [DispId(22)]
    void ImportSpecificFileSystem(FsiFileSystems fileSystemToUse);

    /// <summary>
    /// Roll back to the specified change point
    /// </summary>
    /// <param name="ChangePoint"></param>
    [DispId(23)]
    void RollbackToChangePoint(int ChangePoint);

    /// <summary>
    /// Lock in changes
    /// </summary>
    [DispId(24)]
    void LockInChangePoint();

    /// <summary>
    /// Create a directory item with the specified name
    /// </summary>
    /// <param name="Name"></param>
    /// <returns></returns>
    [DispId(25)]
    IFsiDirectoryItem CreateDirectoryItem(string Name);

    /// <summary>
    /// Create a file item with the specified name
    /// </summary>
    /// <param name="Name"></param>
    /// <returns></returns>
    [DispId(26)]
    IFsiFileItem CreateFileItem(string Name);

    /// <summary>
    /// Volume name
    /// </summary>
    [DispId(27)]
    string VolumeNameUDF { get; }

    /// <summary>
    /// Volume name
    /// </summary>
    [DispId(28)]
    string VolumeNameJoliet { get; }

    /// <summary>
    /// Volume name
    /// </summary>
    [DispId(29)]
    string VolumeNameISO9660 { get; }

    /// <summary>
    /// Indicates whether or not IMAPI should stage the filesystem before the burn.
    /// Set to false to force IMAPI to not stage the filesystem prior to the burn.
    /// </summary>
    [DispId(30)]
    bool StageFiles { get; set; }

    /// <summary>
    /// available multi-session interfaces.
    /// </summary>
    [DispId(40)]
    object[] MultisessionInterfaces { get; set; }
  }

  [TypeLibType(TypeLibTypeFlags.FDual |
               TypeLibTypeFlags.FDispatchable |
               TypeLibTypeFlags.FNonExtensible)]
  [Guid("2C941FD8-975B-59BE-A960-9A2A262853A5")]
  public interface IFileSystemImageResult
  {
    /// <summary>
    /// Image stream
    /// </summary>
    [DispId(1)]
    IStream ImageStream { get; }

    /// <summary>
    /// Progress item block mapping collection
    /// </summary>
    [DispId(2)]
    IProgressItems ProgressItems { get; }

    /// <summary>
    /// Number of blocks in the result image
    /// </summary>
    [DispId(3)]
    int TotalBlocks { get; }

    /// <summary>
    /// Number of bytes in a block
    /// </summary>
    [DispId(4)]
    int BlockSize { get; }

    /// <summary>
    /// Disc Identifier (for identifing imported session of multi-session disc)
    /// </summary>
    [DispId(5)]
    string DiscId { get; }
  }

  [TypeLibType(TypeLibTypeFlags.FDual |
               TypeLibTypeFlags.FDispatchable |
               TypeLibTypeFlags.FNonExtensible)]
  [Guid("2C941FD7-975B-59BE-A960-9A2A262853A5")]
  public interface IProgressItems
  {
    /// <summary>
    /// Get an enumerator for the collection
    /// </summary>
    /// <returns></returns>
    [DispId(-4)]
    [TypeLibFunc(65)]
    IEnumerator GetEnumerator();

    /// <summary>
    /// Find the block mapping from the specified index
    /// </summary>
    /// <param name="Index"></param>
    /// <returns></returns>
    [DispId(0)]
    IProgressItem this[int Index] { get; }

    /// <summary>
    /// Number of items in the collection
    /// </summary>
    [DispId(1)]
    int Count { get; }

    /// <summary>
    /// Find the block mapping from the specified block
    /// </summary>
    /// <param name="block"></param>
    /// <returns></returns>
    [DispId(2)]
    IProgressItem ProgressItemFromBlock(uint block);

    /// <summary>
    /// Find the block mapping from the specified item description
    /// </summary>
    /// <param name="Description"></param>
    /// <returns></returns>
    [DispId(3)]
    IProgressItem ProgressItemFromDescription(string Description);

    /// <summary>
    /// Get a non-variant enumerator
    /// </summary>
    [DispId(4)]
    IEnumProgressItems EnumProgressItems { get; }
  }

  [TypeLibType(TypeLibTypeFlags.FDual |
               TypeLibTypeFlags.FDispatchable |
               TypeLibTypeFlags.FNonExtensible)]
  [Guid("2C941FD4-975B-59BE-A960-9A2A262853A5")]
  public interface IBootOptions
  {
    /// <summary>
    /// Get boot image data stream
    /// </summary>
    [DispId(1)]
    IStream BootImage { get; }

    /// <summary>
    /// Get boot manufacturer
    /// </summary>
    [DispId(2)]
    string Manufacturer { get; set; }

    /// <summary>
    /// Get boot platform identifier
    /// </summary>
    [DispId(3)]
    PlatformId PlatformId { get; set; }

    /// <summary>
    /// Get boot emulation type
    /// </summary>
    [DispId(4)]
    EmulationType Emulation { get; set; }

    /// <summary>
    /// Get boot image size
    /// </summary>
    [DispId(5)]
    uint ImageSize { get; }

    /// <summary>
    /// Set the boot image data stream, emulation type, and image size
    /// </summary>
    /// <param name="newVal"></param>
    [DispId(20)]
    void AssignBootImage(IStream newVal);
  }

  [TypeLibType(TypeLibTypeFlags.FDual |
               TypeLibTypeFlags.FDispatchable |
               TypeLibTypeFlags.FNonExtensible)]
  [Guid("2C941FD9-975B-59BE-A960-9A2A262853A5")]
  public interface IFsiItem
  {
    /// <summary>
    /// Item name
    /// </summary>
    [DispId(11)]
    string Name { get; }

    /// <summary>
    /// Path
    /// </summary>
    [DispId(12)]
    string FullPath { get; }

    /// <summary>
    /// Date and time of creation
    /// </summary>
    [DispId(13)]
    DateTime CreationTime { get; set; }

    /// <summary>
    /// Date and time of last access
    /// </summary>
    [DispId(14)]
    DateTime LastAccessedTime { get; set; }

    /// <summary>
    /// Date and time of last modification
    /// </summary>
    [DispId(15)]
    DateTime LastModifiedTime { get; set; }

    /// <summary>
    /// Flag indicating if item is hidden
    /// </summary>
    [DispId(16)]
    bool IsHidden { get; set; }

    /// <summary>
    /// Name of item in the specified file system
    /// </summary>
    /// <param name="fileSystem"></param>
    /// <returns></returns>
    [DispId(17)]
    string FileSystemName(FsiFileSystems fileSystem);

    /// <summary>
    /// Name of item in the specified file system
    /// </summary>
    /// <param name="fileSystem"></param>
    /// <returns></returns>
    [DispId(18)]
    string FileSystemPath(FsiFileSystems fileSystem);
  }

  [TypeLibType(TypeLibTypeFlags.FDual |
               TypeLibTypeFlags.FDispatchable |
               TypeLibTypeFlags.FNonExtensible)]
  [Guid("2C941FDB-975B-59BE-A960-9A2A262853A5")]
  public interface IFsiFileItem
  {
    // IFsiItem
    /// <summary>
    /// Item name
    /// </summary>
    [DispId(11)]
    string Name { get; }

    /// <summary>
    /// Path
    /// </summary>
    [DispId(12)]
    string FullPath { get; }

    /// <summary>
    /// Date and time of creation
    /// </summary>
    [DispId(13)]
    DateTime CreationTime { get; set; }

    /// <summary>
    /// Date and time of last access
    /// </summary>
    [DispId(14)]
    DateTime LastAccessedTime { get; set; }

    /// <summary>
    /// Date and time of last modification
    /// </summary>
    [DispId(15)]
    DateTime LastModifiedTime { get; set; }

    /// <summary>
    /// Flag indicating if item is hidden
    /// </summary>
    [DispId(16)]
    bool IsHidden { get; set; }

    /// <summary>
    /// Name of item in the specified file system
    /// </summary>
    /// <param name="fileSystem"></param>
    /// <returns></returns>
    [DispId(17)]
    string FileSystemName(FsiFileSystems fileSystem);

    /// <summary>
    /// Name of item in the specified file system
    /// </summary>
    /// <param name="fileSystem"></param>
    /// <returns></returns>
    [DispId(18)]
    string FileSystemPath(FsiFileSystems fileSystem);

    // IFsiFileItem
    /// <summary>
    /// Data byte count
    /// </summary>
    [DispId(41)]
    long DataSize { get; }

    /// <summary>
    /// Lower 32 bits of the data byte count
    /// </summary>
    [DispId(42)]
    int DataSize32BitLow { get; }

    /// <summary>
    /// Upper 32 bits of the data byte count
    /// </summary>
    [DispId(43)]
    int DataSize32BitHigh { get; }

    /// <summary>
    /// Data stream
    /// </summary>
    [DispId(44)]
    IStream Data { get; set; }
  }

  [TypeLibType(TypeLibTypeFlags.FDual |
               TypeLibTypeFlags.FDispatchable |
               TypeLibTypeFlags.FNonExtensible)]
  [Guid("2C941FDC-975B-59BE-A960-9A2A262853A5")]
  public interface IFsiDirectoryItem
  {
    // IFsiItem
    /// <summary>
    /// Item name
    /// </summary>
    [DispId(11)]
    string Name { get; }

    /// <summary>
    /// Path
    /// </summary>
    [DispId(12)]
    string FullPath { get; }

    /// <summary>
    /// Date and time of creation
    /// </summary>
    [DispId(13)]
    DateTime CreationTime { get; set; }

    /// <summary>
    /// Date and time of last access
    /// </summary>
    [DispId(14)]
    DateTime LastAccessedTime { get; set; }

    /// <summary>
    /// Date and time of last modification
    /// </summary>
    [DispId(15)]
    DateTime LastModifiedTime { get; set; }

    /// <summary>
    /// Flag indicating if item is hidden
    /// </summary>
    [DispId(16)]
    bool IsHidden { get; set; }

    /// <summary>
    /// Name of item in the specified file system
    /// </summary>
    /// <param name="fileSystem"></param>
    /// <returns></returns>
    [DispId(17)]
    string FileSystemName(FsiFileSystems fileSystem);

    /// <summary>
    /// Name of item in the specified file system
    /// </summary>
    /// <param name="fileSystem"></param>
    /// <returns></returns>
    [DispId(18)]
    string FileSystemPath(FsiFileSystems fileSystem);

    // IFsiDirectoryItem
    /// <summary>
    /// Get an enumerator for the collection
    /// </summary>
    /// <returns></returns>
    [DispId(-4)]
    [TypeLibFunc(65)]
    IEnumerator GetEnumerator();

    /// <summary>
    /// Get the item with the given relative path
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    [DispId(0)]
    IFsiItem this[string path] { get; }

    /// <summary>
    /// Number of items in the collection
    /// </summary>
    [DispId(1)]
    int Count { get; }

    /// <summary>
    /// Get a non-variant enumerator
    /// </summary>
    [DispId(2)]
    IEnumFsiItems EnumFsiItems { get; }

    /// <summary>
    /// Add a directory with the specified relative path
    /// </summary>
    /// <param name="path"></param>
    [DispId(30)]
    void AddDirectory(string path);

    /// <summary>
    /// Add a file with the specified relative path and data
    /// </summary>
    /// <param name="path"></param>
    /// <param name="fileData"></param>
    [DispId(31)]
    void AddFile(string path, IStream fileData);

    /// <summary>
    /// Add files and directories from the specified source directory
    /// </summary>
    /// <param name="sourceDirectory"></param>
    /// <param name="includeBaseDirectory"></param>
    [DispId(32)]
    void AddTree(string sourceDirectory, bool includeBaseDirectory);

    /// <summary>
    /// Add an item
    /// </summary>
    /// <param name="Item"></param>
    [DispId(33)]
    void Add(IFsiItem Item);

    /// <summary>
    /// Remove an item with the specified relative path
    /// </summary>
    /// <param name="path"></param>
    [DispId(34)]
    void Remove(string path);

    /// <summary>
    /// Remove a subtree with the specified relative path
    /// </summary>
    /// <param name="path"></param>
    [DispId(35)]
    void RemoveTree(string path);
  }

  [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  [Guid("2C941FDA-975B-59BE-A960-9A2A262853A5")]
  public interface IEnumFsiItems
  {
    /// <summary>
    /// Get next items in the enumeration
    /// </summary>
    /// <param name="celt"></param>
    /// <param name="rgelt"></param>
    /// <param name="pceltFetched"></param>
    void Next(uint celt, out IFsiItem rgelt, out uint pceltFetched);

    /// <summary>
    /// Remoting support for Next (allow NULL pointer for item count when 
    /// requesting single item)
    /// </summary>
    /// <param name="celt"></param>
    /// <param name="rgelt"></param>
    /// <param name="pceltFetched"></param>
    void RemoteNext(uint celt, out IFsiItem rgelt, out uint pceltFetched);

    /// <summary>
    /// Skip items in the enumeration
    /// </summary>
    /// <param name="celt"></param>
    void Skip(uint celt);

    /// <summary>
    /// Reset the enumerator
    /// </summary>
    void Reset();

    /// <summary>
    /// Make a copy of the enumerator
    /// </summary>
    /// <param name="ppEnum"></param>
    void Clone(out IEnumFsiItems ppEnum);
  }

  [TypeLibType(TypeLibTypeFlags.FDual |
               TypeLibTypeFlags.FDispatchable |
               TypeLibTypeFlags.FNonExtensible)]
  [Guid("2C941FD5-975B-59BE-A960-9A2A262853A5")]
  public interface IProgressItem
  {
    /// <summary>
    /// Progress item description
    /// </summary>
    [DispId(1)]
    string Description { get; }

    /// <summary>
    /// First block in the range of blocks used by the progress item
    /// </summary>
    [DispId(2)]
    uint FirstBlock { get; }

    /// <summary>
    /// Last block in the range of blocks used by the progress item
    /// </summary>
    [DispId(3)]
    uint LastBlock { get; }

    /// <summary>
    /// Number of blocks used by the progress item
    /// </summary>
    [DispId(4)]
    uint BlockCount { get; }
  }

  [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  [Guid("2C941FD6-975B-59BE-A960-9A2A262853A5")]
  public interface IEnumProgressItems
  {
    /// <summary>
    /// Get next items in the enumeration
    /// </summary>
    /// <param name="celt"></param>
    /// <param name="rgelt"></param>
    /// <param name="pceltFetched"></param>
    void Next(uint celt, out IProgressItem rgelt, out uint pceltFetched);

    /// <summary>
    /// Remoting support for Next (allow NULL pointer for item count when 
    /// requesting single item)
    /// </summary>
    /// <param name="celt"></param>
    /// <param name="rgelt"></param>
    /// <param name="pceltFetched"></param>
    void RemoteNext(uint celt, out IProgressItem rgelt, out uint pceltFetched);

    /// <summary>
    /// Skip items in the enumeration
    /// </summary>
    /// <param name="celt"></param>
    void Skip(uint celt);

    /// <summary>
    /// Reset the enumerator
    /// </summary>
    void Reset();

    /// <summary>
    /// Make a copy of the enumerator
    /// </summary>
    /// <param name="ppEnum"></param>
    void Clone(out IEnumProgressItems ppEnum);
  }

  [TypeLibType(TypeLibTypeFlags.FCanCreate)]
  [ClassInterface(ClassInterfaceType.None)]
  [ComSourceInterfaces("DDiscMaster2Events\0")]
  [Guid("2735412E-7F64-5B0F-8F00-5D77AFBE261E"), ComImport]
  public class MsftDiscMaster2Class
  {
  }

  [TypeLibType(TypeLibTypeFlags.FCanCreate)]
  [ClassInterface(ClassInterfaceType.None)]
  [Guid("2735412D-7F64-5B0F-8F00-5D77AFBE261E"), ComImport]
  public class MsftDiscRecorder2Class
  {
  }

  [TypeLibType(TypeLibTypeFlags.FCanCreate)]
  [ClassInterface(ClassInterfaceType.None)]
  [ComSourceInterfaces("DDiscFormat2DataEvents\0")]
  [Guid("2735412A-7F64-5B0F-8F00-5D77AFBE261E"), ComImport]
  public class MsftDiscFormat2DataClass
  {
  }
  



  [TypeLibType(TypeLibTypeFlags.FCanCreate)]
  [ClassInterface(ClassInterfaceType.None)]
  [ComSourceInterfaces("DFileSystemImageEvents\0")]
  [Guid("2C941FC5-975B-59BE-A960-9A2A262853A5"), ComImport]
  public class MsftFileSystemImageClass
  {
  }

  [TypeLibType(TypeLibTypeFlags.FCanCreate)]
  [ClassInterface(ClassInterfaceType.None)]
  [Guid("2C941FCE-975B-59BE-A960-9A2A262853A5")]
  public class MsftBootOptionsClass
  {
  }

  [TypeLibType(TypeLibTypeFlags.FCanCreate)]
  [ClassInterface(ClassInterfaceType.None)]
  [Guid("27354123-7F64-5B0F-8F00-5D77AFBE261E")]
  public class MsftWriteSpeedDescriptorClass
  {
  }
}